package cn.fl.institution.controller;

import cmm.mid.core.framework.dto.DataResultDTO;
import cmm.mid.core.framework.page.DataResultVO;
import cn.cmm.base.framework.constant.BaseConstant;
import cn.cmm.base.framework.exception.BaseException;
import cn.cmm.base.framework.logger.eum.LogExceptionEnum;
import cn.cmm.base.framework.utils.BaseLogUtils;
import cn.cmm.base.framework.utils.CollectionUtils;
import cn.cmm.base.framework.utils.DecimalUtils;
import cn.fl.customer.service.ICstNpBscInfoService;
import cn.fl.customer.vo.CstNpBscInfoVO;
import cn.fl.enums.InsAccResEnum;
import cn.fl.framework.constant.DictionaryConstant;
import cn.fl.institution.api.PrjBscInfoInsXyflService;
import cn.fl.project.api.IPrjCstAccInfoApiService;
import cn.fl.project.condition.PrjCstAccInfoQueryCondition;
import cn.fl.project.constant.PrjBscInfoConstant;
import cn.fl.project.service.IPrjCstAccInfoService;
import cn.fl.project.vo.PrjCstAccInfoVO;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;

/**
 * @Description: 兴业金租银行信息采集
 * @Author: Fuzq
 * @Date: 15:00 2020-02-17
 * @Version V1.0
 */
@RestController
@RequestMapping(value = "/institution/xyfl")
public class PrjBscInfoInsXyflController {

    @Autowired
    private IPrjCstAccInfoService prjCstAccInfoService;
    @Autowired
    private IPrjCstAccInfoApiService prjCstAccInfoApiService;
    @Autowired
    private PrjBscInfoInsXyflService prjBscInfoInsXyflService;
    @Autowired
    private ICstNpBscInfoService cstNpBscInfoService;


    /**
     * @param prjCstAccInfoCondition
     * @return cmm.mid.core.framework.page.DataResultVO
     * @description 银行信息采集保存
     * @author fuzq
     * @date 2020-02-19
     */
    @RequestMapping(value = "/savexyfl.do", method = RequestMethod.POST)
    public DataResultVO saveForXyfl(PrjCstAccInfoQueryCondition prjCstAccInfoCondition, HttpServletRequest request) {
        BaseLogUtils.newServiceLogger("兴业金租-银行信息采集保存 prjCstAccInfoCondition" + JSONObject.toJSONString(prjCstAccInfoCondition));
        DataResultVO dataResultVO = new DataResultVO(BaseConstant.IS_YESNO_YES, "保存成功");
        //更新自然人基本信息
        //页面信息是否变更
        boolean isChange = bscInfoComparison(prjCstAccInfoCondition);
        //验证码校验
        boolean isSuccess = false;
        try {
            isSuccess = prjBscInfoInsXyflService.rePaymentIdentify(prjCstAccInfoCondition.getInsId(), prjCstAccInfoCondition.getPrjId(),
                    prjCstAccInfoCondition.getCstId(), prjCstAccInfoCondition.getPhoneCode());
        } catch (Exception e) {
            BaseLogUtils.newServiceLogger("兴业金租-银行信息采集验证码验证：接口调用失败").error(LogExceptionEnum.API_CODE_0101, e);
            return new DataResultVO(BaseConstant.IS_YESNO_NO, "兴业金租-银行信息采集验证码验证：接口调用失败");
        }
        if (isSuccess && !isChange) {
            //更新账户信息
            prjCstAccInfoCondition.setAccResCd(InsAccResEnum.SUCCESS.code);
            prjCstAccInfoCondition.setAccResMsg("开户成功");
            try {
                prjCstAccInfoApiService.modifyPrjAccInfo(prjCstAccInfoCondition);
            } catch (BaseException e) {
                BaseLogUtils.newServiceLogger("兴业金租-银行信息采集账户信息更细失败").error(LogExceptionEnum.API_CODE_0101, e);
                return new DataResultVO(BaseConstant.IS_YESNO_NO, "账户信息更新失败");
            }
            //更新自然人基本信息
            try {
                saveCstNpBscInfo(request, prjCstAccInfoCondition);
            } catch (Exception e) {
                BaseLogUtils.newServiceLogger("兴业金租-银行信息采集自然人基本信息更新失败").error(LogExceptionEnum.API_CODE_0101, e);
                return new DataResultVO(BaseConstant.IS_YESNO_NO, "自然人信息更新失败");
            }
        } else {
            BaseLogUtils.newServiceLogger("兴业金租-银行信息采集 接口校验是否通过: " + isSuccess + " , 页面信息是否变更: " + isChange).info();
            return new DataResultVO(BaseConstant.IS_YESNO_NO, "接口校验: " + isSuccess + "页面信息变更:" + isChange + "请重新获取短信验证码!");
        }
        BaseLogUtils.newServiceLogger("兴业金租-银行信息采集requestBody: " + JSONObject.toJSONString(prjCstAccInfoCondition)).info();

        return dataResultVO;
    }

    /**
     * @param prjCstAccInfoQueryCondition
     * @return cmm.mid.core.framework.page.DataResultVO
     * @description 兴业金租获取验证码
     * @author fuzq
     * @date 2020-02-19
     */
    @RequestMapping(value = "/verifycode.do", method = RequestMethod.POST)
    public DataResultVO getVerifyCode(PrjCstAccInfoQueryCondition prjCstAccInfoQueryCondition) {
        DataResultVO dataResultVO = null;
        BaseLogUtils.newServiceLogger("兴业金租-银行信息采集获取验证码requestBody: " + JSONObject.toJSONString(prjCstAccInfoQueryCondition)).info();
        //保存项目信息、返回四要素验证结果
        DataResultDTO dataResultDTO = null;
        try {
            dataResultDTO = fourFactorVerification(prjCstAccInfoQueryCondition);
        } catch (BaseException e) {
            BaseLogUtils.newServiceLogger("兴业金租-银行信息采集四要素验证异常").error(LogExceptionEnum.API_CODE_0101, e);
            return new DataResultVO(BaseConstant.IS_YESNO_NO, "兴业金租-银行信息采集四要素验证异常");
        }
        BaseLogUtils.newServiceLogger("兴业金租-银行信息采集保存项目信息返回四要素验证结果: " + JSONObject.toJSONString(dataResultDTO)).info();
        //判断四要素校验结果.
        try {
            dataResultVO = fourFactorVerificationResult(dataResultDTO);
        } catch (Exception e) {
            BaseLogUtils.newServiceLogger("兴业金租-银行信息采集判断四要素校验结果异常").error(LogExceptionEnum.API_CODE_0101, e);
            return new DataResultVO(BaseConstant.IS_YESNO_NO, "兴业金租-银行信息采集判断四要素校验结果异常");
        }
        BaseLogUtils.newServiceLogger("兴业金租-银行信息采集判断四要素校验结果: " + JSONObject.toJSONString(dataResultVO)).info();
        //四要素校验通过-调用接口发送验证码
        try {
            accountOpeningAndSendVerificationCode(prjCstAccInfoQueryCondition, dataResultDTO, dataResultVO);
        } catch (Exception e) {
            BaseLogUtils.newServiceLogger("兴业金租-银行信息采集调用接口发送验证码异常").error(LogExceptionEnum.API_CODE_0101, e);
            return new DataResultVO(BaseConstant.IS_YESNO_NO, "兴业金租-银行信息采集调用接口发送验证码异常");
        }
        return dataResultVO;
    }

    /**
     * @param prjCstAccInfoQueryCondition
     * @param dataResultDTO
     * @param dataResultVO
     * @return void
     * @description 四要素校验通过-调用接口发送验证码
     * @author fuzq
     * @date 2020-02-20
     */
    private void accountOpeningAndSendVerificationCode(PrjCstAccInfoQueryCondition prjCstAccInfoQueryCondition, DataResultDTO dataResultDTO, DataResultVO dataResultVO) throws Exception {
        if (BaseConstant.IS_YESNO_YES == dataResultVO.getSuccess()) {
            //先更新四要素校验
            prjCstAccInfoApiService.modifyPrjAccInfo(prjCstAccInfoQueryCondition);
            dataResultDTO = prjBscInfoInsXyflService.rePaymentRegister(prjCstAccInfoQueryCondition.getInsId(), prjCstAccInfoQueryCondition.getPrjId(), prjCstAccInfoQueryCondition.getCstId(), dataResultDTO);
            if (dataResultDTO.getSuccess() == BaseConstant.IS_YESNO_YES) {
                try {
                    prjCstAccInfoApiService.modifyPrjAccInfo(prjCstAccInfoQueryCondition);
                } catch (BaseException e) {
                    BaseLogUtils.newServiceLogger("兴业金租-开户状态 update fail").error(LogExceptionEnum.API_CODE_0101, e);
                }
            }
            dataResultVO.setInfo(dataResultDTO.getInfo());
            dataResultVO.setSuccess(dataResultDTO.getSuccess());

        }
    }

    /**
     * @param prjCstAccInfoQueryCondition
     * @return cmm.mid.core.framework.dto.DataResultDTO
     * @description 四要素验证-查询
     * @author fuzq
     * @date 2020-02-19
     */
    private DataResultDTO fourFactorVerification(PrjCstAccInfoQueryCondition prjCstAccInfoQueryCondition) throws BaseException {
        PrjCstAccInfoQueryCondition prjCstAccInfo = new PrjCstAccInfoQueryCondition();
        prjCstAccInfo.setPrjId(prjCstAccInfoQueryCondition.getPrjId());
        prjCstAccInfo.setIsDel(BaseConstant.IS_YESNO_NO);
        prjCstAccInfo.setInsCode(PrjBscInfoConstant.PRJ_INS_CODE_XYFL);
        List<PrjCstAccInfoVO> prjCstAccInfoVOS = this.prjCstAccInfoService.searchList(prjCstAccInfo);
        if (CollectionUtils.isNotEmpty(prjCstAccInfoVOS)) {
            PrjCstAccInfoVO prjCstAccInfoVO = prjCstAccInfoVOS.get(0);
            prjCstAccInfoQueryCondition.setId(prjCstAccInfoVO.getId());
        }
        // 四要素验证
        prjCstAccInfoQueryCondition.setCertTypCd(DictionaryConstant.CODE_CERT_TYP_CD_0);
        prjCstAccInfoQueryCondition.setAccNo(prjCstAccInfoQueryCondition.getAccNo());
        prjCstAccInfoQueryCondition.setAccNm(prjCstAccInfoQueryCondition.getCstNm());
        prjCstAccInfoQueryCondition.setInsCode(PrjBscInfoConstant.PRJ_INS_CODE_XYFL);
        return prjCstAccInfoApiService.modifyPrjAccInfo(prjCstAccInfoQueryCondition);
    }

    /**
     * @param dataResultDTO
     * @return cmm.mid.core.framework.page.DataResultVO
     * @description 判断四要素验证结果
     * @author fuzq
     * @date 2020-02-19
     */
    private DataResultVO fourFactorVerificationResult(DataResultDTO dataResultDTO) {
        DataResultVO dataResultVO = new DataResultVO(BaseConstant.IS_YESNO_YES, "四要素校验通过");
        String chkRstCd = null;
        String bankCardType = null;
        Map<String, String> ckResMap = null;
        if (dataResultDTO != null) {
            if ("0".equals(dataResultDTO.getCode())) {
                dataResultVO.setSuccess(BaseConstant.IS_YESNO_NO);
                dataResultVO.setInfo("四要素校验不通过");
                return dataResultVO;
            }
            if (dataResultDTO.getData() != null) {
                ckResMap = (Map<String, String>) dataResultDTO.getData();
                chkRstCd = ckResMap.get("chkRstCd");
                bankCardType = ckResMap.get("bankCardType");
                //验证返回结果成功
                if (!"1".equals(chkRstCd)) {
                    dataResultVO.setSuccess(BaseConstant.IS_YESNO_NO);
                    dataResultVO.setInfo("四要素校验不通过");
                    return dataResultVO;
                }
                if (!"0".equals(bankCardType)) {
                    dataResultVO.setSuccess(BaseConstant.IS_YESNO_NO);
                    dataResultVO.setInfo("不支持此类银行卡，请更换为借记卡");
                    return dataResultVO;
                }
            }
        } else {
            dataResultVO.setSuccess(BaseConstant.IS_YESNO_NO);
            dataResultVO.setInfo("四要素验证返回空");
            return dataResultVO;
        }
        return dataResultVO;
    }

    /**
     * @param prjCstAccInfoCondition
     * @return boolean
     * @description 判断获取验证码后页面信息时候改变(false为改变 ， true为未改变)
     * @author fuzq
     * @date 2020-02-19
     */
    private boolean bscInfoComparison(PrjCstAccInfoQueryCondition prjCstAccInfoCondition) {
        PrjCstAccInfoQueryCondition cstAccInfoQueryCondition = new PrjCstAccInfoQueryCondition();
        cstAccInfoQueryCondition.setPrjId(prjCstAccInfoCondition.getPrjId());
        cstAccInfoQueryCondition.setInsCode(prjCstAccInfoCondition.getInsCode());
        cstAccInfoQueryCondition.setCstId(prjCstAccInfoCondition.getCstId());
        List<PrjCstAccInfoVO> prjCstAccInfoVOS = this.prjCstAccInfoService.searchList(cstAccInfoQueryCondition);
        if (!CollectionUtils.isEmpty(prjCstAccInfoVOS)) {
            PrjCstAccInfoVO prjCstAccInfoVO = prjCstAccInfoVOS.get(0);
            if (!prjCstAccInfoCondition.getBkNm().equals(prjCstAccInfoVO.getBkNm())) {
                return true;
            }
            if (!prjCstAccInfoCondition.getBkCd().equals(prjCstAccInfoVO.getBkCd())) {
                return true;
            }
            if (!prjCstAccInfoCondition.getMp().equals(prjCstAccInfoVO.getMp())) {
                return true;
            }
            if (!prjCstAccInfoCondition.getAccNo().equals(prjCstAccInfoVO.getAccNo())) {
                return true;
            }
        }
        return false;
    }

    /**
     * @param request
     * @return void
     * @description 更新自然人信息
     * @author fuzq
     * @date 2020-02-25
     */
    private void saveCstNpBscInfo(HttpServletRequest request, PrjCstAccInfoQueryCondition prjCstAccInfoQueryCondition) throws BaseException {
        //月收入(元)
        Long mrIncMoney = DecimalUtils.convertYuanToFen(Double.valueOf(prjCstAccInfoQueryCondition.getMonthlyIncome()));
        // 月收入转换年收入
        Double yrInc = DecimalUtils.mul(mrIncMoney.doubleValue(), 12d);
        //民族
        String nation = request.getParameter("nation");
        //户籍省
        String rgnPrCd2 = request.getParameter("rgnPrCd2");
        //户籍市
        String rgnCyCd2 = request.getParameter("rgnCyCd2");
        //居住省
        String rgnPrCd = request.getParameter("rgnPrCd");
        //居住市
        String rgnCyCd = request.getParameter("rgnCyCd");
        //身份证有效截止日期
        String certEndDate = request.getParameter("certValidEDt");
        CstNpBscInfoVO cstNpBscInfoVO = cstNpBscInfoService.selectById(Long.valueOf(request.getParameter("cstId")));
        cstNpBscInfoVO.setYrInc(yrInc.longValue());
        cstNpBscInfoVO.setNation(nation);
        cstNpBscInfoVO.setCertValidEDt(certEndDate);
        cstNpBscInfoVO.setDomicileProvince(rgnPrCd);
        cstNpBscInfoVO.setDomicleCity(rgnCyCd);
        cstNpBscInfoVO.setPostProvince(rgnPrCd2);
        cstNpBscInfoVO.setPostCity(rgnCyCd2);
        cstNpBscInfoService.modify(cstNpBscInfoVO);
    }

}
